<?php

namespace App\Http\Controllers;

/**
 * 微信授权相关接口
 *
 * @link http://www.phpddt.com
 */
class WechatController extends Controller
{

    private $appletAppid = '';
    private $appletAppsecret = '';

    public function __construct()
    {
        $wxApplet = config('pay.wechat_applet');
        $this->appletAppid = $wxApplet['appid'];
        $this->appletAppsecret = $wxApplet['app_secret'];
    }

    /**
     * 判断是否是微信
     * @return bool
     */
    public function is_weixin()
    {
        if (strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false) {
            return true;
        }
        return false;
    }

    /**
     * 获取微信授权链接
     * @param string $redirect_uri 跳转地址
     * @param mixed $state 参数
     */
    public function get_authorize_url($url, $state = 'WECHAT')
    {
        $wxConfig = config('pay.wechat_account');
        $redirect_uri = urlencode($url);
        return "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$wxConfig['appid']}&redirect_uri={$redirect_uri}&response_type=code&scope=snsapi_userinfo&state={$state}#wechat_redirect";
    }

    /**
     * 获取授权token
     *
     * @param string $code 通过get_authorize_url获取到的code
     */
    public function get_access_token($code)
    {
        $wxConfig = config('pay.wechat_account');
        $token_url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$wxConfig['appid']}&secret={$wxConfig['app_secret']}&code={$code}&grant_type=authorization_code";
        $token_data = $this->http($token_url);

        if ($token_data[0] == 200) {
            return json_decode($token_data[1], TRUE);
        }

        return FALSE;
    }

    public function get_token()
    {
        $wxConfig = config('pay.wechat_account');
        $token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$wxConfig['appid']}&secret={$wxConfig['app_secret']}";
        $data = $this->http($token_url);
        if ($data[0] == 200) {
            return json_decode($data[1], true);
        }

        return false;
    }

    public function get_token_app()
    {
        $wxConfig = config('wechat_applet');
        $token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$wxConfig['app_id']}&secret={$wxConfig['app_secret']}";
        $data = $this->http($token_url);
        if ($data[0] == 200) {
            return json_decode($data[1], true);
        }

        return false;
    }

    /**
     * 获取授权后的微信用户信息
     * @param string $access_token
     * @param string $open_id
     */
    public function get_user_info($access_token, $open_id)
    {
        if ($access_token && $open_id) {
            /* $info_url = "https://api.weixin.qq.com/sns/userinfo?access_token={$access_token}&openid={$open_id}&lang=zh_CN";*/
            $info_url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token={$access_token}&openid={$open_id}&lang=zh_CN";
            $info_data = $this->http($info_url);

            if ($info_data[0] == 200) {
                return json_decode($info_data[1], TRUE);
            }
        }

        return FALSE;
    }

    public function get_qrcode($access_token, $scene, $page)
    {
        if ($access_token) {
            $url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={$access_token}";
//            $url = 'https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=' . $access_token;
            $post_data = [
//                'access_token' => $access_token,
                'scene' => $scene,
                'page' => $page,
//                'width' => 430,
//                'auto_color' => false,
//                'line_color' => json_encode(["r" => 0, "g" => 0, "b" => 0]),
//                'is_hyaline' => false
            ];
//p(json_encode($post_data));
            $info_data = $this->post_curl($url, json_encode($post_data));

            return $info_data;
        }

        return FALSE;
    }

    public function http($url, $method = 'post', $postfields = null, $headers = array(), $debug = false)
    {
        $ci = curl_init();
        /* Curl settings */
        curl_setopt($ci, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
        curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 30);
        curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ci, CURLOPT_TIMEOUT, 30);
        curl_setopt($ci, CURLOPT_RETURNTRANSFER, true);

        switch ($method) {
            case 'POST':
                curl_setopt($ci, CURLOPT_POST, true);
                if (!empty($postfields)) {
                    curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields);
                    $this->postdata = $postfields;
                }
                break;
        }
        curl_setopt($ci, CURLOPT_URL, $url);
        curl_setopt($ci, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ci, CURLINFO_HEADER_OUT, true);

        $response = curl_exec($ci);
        $http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);

        if ($debug) {
            echo "=====post data======\r\n";
            var_dump($postfields);

            echo '=====info=====' . "\r\n";
            print_r(curl_getinfo($ci));

            echo '=====$response=====' . "\r\n";
            print_r($response);
        }
        curl_close($ci);
        return array($http_code, $response);
    }

    function createNoncestr($length = 32)
    {

        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";

        $str = "";

        for ($i = 0; $i < $length; $i++) {

            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);

        }
        return $str;
    }

    function arraytoxml($data)
    {
        $str = '<xml>';
        foreach ($data as $k => $v) {
            $str .= '<' . $k . '>' . $v . '</' . $k . '>';
        }
        $str .= '</xml>';
        return $str;
    }

    public function getSign($Obj, $key)
    {
        foreach ($Obj as $k => $v) {
            $Parameters[$k] = $v;
        }
        //签名步骤一：按字典序排序参数
        ksort($Parameters);
        $String = self::formatBizQueryParaMap($Parameters, false);
        //echo '【string1】'.$String.'</br>';
        //签名步骤二：在string后加入KEY
        $String = $String . $key;
        //echo "【string2】".$String."</br>";
        //签名步骤三：MD5加密
        $String = md5($String);
        //echo "【string3】 ".$String."</br>";
        //签名步骤四：所有字符转为大写
        $result_ = strtoupper($String);
        //echo "【result】 ".$result_."</br>";
        return $result_;
    }

    function formatBizQueryParaMap($paraMap, $urlencode)
    {
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v) {
            if ($urlencode) {
                $v = urlencode($v);
            }
            //$buff .= strtolower($k) . "=" . $v . "&";
            $buff .= $k . "=" . $v . "&";
        }
        if (strlen($buff) > 0) {
            $reqPar = substr($buff, 0, strlen($buff) - 1);
        }
        return $reqPar;
    }

    /**
     * 分享
     * @param $timestamp
     * @return bool|string
     */
    public function share($timestamp, $appurl)
    {
        $wxInfo = config('pay.wechat_info');
        $file = "access_token.txt";

        if (file_exists($file)) {

            $fp = fopen($file, "r");

            $access_token = fread($fp, filesize($file));

        } else {

            $access_token = self::getToken($file);

        }

        //获取jsticket
        $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" . $access_token . "&type=jsapi";

        $rurl = file_get_contents($url);

        $rurl = json_decode($rurl, true);

        if ($rurl['errcode']) {

            $access_token = self::getToken($file);

            $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" . $access_token . "&type=jsapi";

            $rurl = file_get_contents($url);

            $rurl = json_decode($rurl, true);

            $jsapi_ticket = $rurl['ticket'];

        } else {

            $jsapi_ticket = $rurl['ticket'];

        }

        $string1 = 'jsapi_ticket=' . $jsapi_ticket . '&noncestr=' . $wxInfo['noncestr'] . '&timestamp=' . $timestamp . '&url=' . $appurl;

        $signature = sha1($string1);
        $wxAccount = config('pay.wechat_account');
        $data = [
            "appId" => $wxAccount['appid'],
            "nonceStr" => $wxInfo['noncestr'],
            "timestamp" => $timestamp,
            "signature" => $signature
        ];

        return ['status' => 1, 'data' => $data];

    }

    /**
     * 得到token
     * @param $file
     * @return mixed
     */
    public function getToken($file)
    {
        $wxAccount = config('pay.wechat_account');
        $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $wxAccount['appid'] . '&secret=' . $wxAccount['app_secret'];
        $rurl = file_get_contents($url);
        $rurl = json_decode($rurl, true);
        $access_token = $rurl['access_token'];
        $fp = fopen($file, 'w');
        fwrite($fp, '');
        fwrite($fp, $access_token);
        return $access_token;
    }

    /**
     * 小程序获取openid,curl的方式
     * @return string
     */
    public function get_open_id_wechat($code)
    {
        $curl = curl_init();
        //使用curl_setopt() 设置要获得url地址
        $url = 'https://api.weixin.qq.com/sns/jscode2session?appid=' . $this->appletAppid . '&secret=' . $this->appletAppsecret . '&js_code=' . $code . '&grant_type=authorization_code';
        curl_setopt($curl, CURLOPT_URL, $url);
        //设置是否输出header
        curl_setopt($curl, CURLOPT_HEADER, false);
        //设置是否输出结果
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

        //设置是否检查服务器端的证书
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        //使用curl_exec()将curl返回的结果转换成正常数据并保存到一个变量中
        $data = curl_exec($curl);
        //关闭会话
        curl_close($curl);

        $dataArr = json_decode($data, true);
        return $dataArr;
    }

    /**
     * 获取小程序的openid，file_get_contents的方式
     * @return mixed
     */
    public function wxGetOpenidByCode($code)
    {
        $applet = config('wechat_applet');

        $appid = $applet['app_id'];
        $secret = $applet['key'];
        $url = "https://api.weixin.qq.com/sns/jscode2session?appid={$appid}&secret={$secret}&js_code={$code}&grant_type=authorization_code";
        //通过code换取网页授权access_token
        $weixin = file_get_contents($url);
        $jsondecode = json_decode($weixin); //对JSON格式的字符串进行编码
        $array = get_object_vars($jsondecode);//转换成数组

        return $array;
    }

    /**
     * 获取票据
     * @param $scene_id
     * @return mixed
     */
    public function getWCode($scene_id)
    {
        $access_token = $this->getAccessToken();
        $qrcode_url = 'https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=' . $access_token;
        $postJson = "{\"expire_seconds\": 86400, \"action_name\": \"QR_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": {$scene_id}}}}";;
        $result = $this->post_curl($qrcode_url, $postJson);

        return json_decode($result, true);
    }

    /**
     * 获取acces_token
     * @return mixed
     */
    public function getAccessToken($type = 1)
    {
        if ($type == 1) {
            $wxConfig = config('wechat_account');
        } else {
            $wxConfig = config('wechat_applet');
        }

//        ' login url' => https:/ /api . welxin. qq. com/ sns 1 Jscode2session? appid=%s&secret=%s&js_ code%s&grant_ type=authorization_ code . ,
        $access_token_url = sprintf('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s', $wxConfig['app_id'], $wxConfig['app_secret']);

        if (!session('access_token')) {
            $result = $this->get_curl($access_token_url);
            $access_token = $result['access_token'];
            session('access_token', $access_token, 7000);
        } else {
            $access_token = session('access_token');
        }

        return $access_token;
    }

    /**
     * 发送小程序消息
     * @param string $touser
     * @param string $template_id
     * @param $page
     * @param $dataArray
     * @return array
     */
    public function sendMsg($touser, $template_id, $page, $dataArray)
    {
        //access_token 一般都存在缓存 ,
        $access_token = $this->getAccessToken(2);
        //请求url
        $url = 'https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=' . $access_token;

        //发送内容
        $data = [];
        $data['touser'] = $touser;  //用户的openid
        $data['template_id'] = $template_id; //所需下发的订阅模板id

        //点击模板卡片后的跳转页面，仅限本小程序内的页面。支持带参数,（示例index?foo=bar）。该字段不填则模板无跳转。
        $data['page'] = $page;
        //模板内容，格式形如 { "key1": { "value": any }, "key2": { "value": any } }
        $data['data'] = $dataArray;

        //跳转小程序类型：developer为开发版；trial为体验版；formal为正式版；默认为正式版
        $data['miniprogram_state'] = 'trial';
        $data['lang'] = 'zh_CN';
        $json_data = json_encode($data);

        $data = self::post_curl($url, $json_data);
        p($data);
        return [
            'openid' => $touser,
            'data' => self::post_curl($url, $json_data)//这里面就是个curl请求 , 转成数组返回
        ];

//        $data = [
//            'touser' => '用户openid',
//            'url' => $web_url = "http://" . $_SERVER['SERVER_NAME'],
//            'topcolor' => "#FF0000",
//            'data' => array(
//                'name' => array('value' => "bangbangbang1", 'color' => "#fc0101"),
//                'content' => array('value' => '给你留言了', 'color' => "#173177"),
//                'time' => array('value' => date('Y-m-d H:i:s', time()), 'color' => "#173177"),
//            )
//        ];
//        $get_all_access_token = $this->get_all_access_token();
//
//        $json_data = json_encode($data);//转化成json数组让微信可以接收
//        $url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" . $get_all_access_token;//模板消息请求URL
//        $res = self::post_curl($url, urldecode($json_data));//请求开始
//        $res = json_decode($res, true);
//
//        if ($res['errcode'] == 0 && $res['errmsg'] == "ok") {
//            return json(['st' => 1, 'msg' => '发送成功']);
//        } else {
//            return json(['st' => 0, 'msg' => '发送失败']);
//        }
    }

    public function get_all_access_token()
    {
        $wxConfig = config('wechat_account');
        $appid = $wxConfig->app_id;
        $secret = $wxConfig->app_secret;
        $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $appid . '&secret=' . $secret;
        $res = json_decode(self::get_curl($url), true);

        $access_token = $res['access_token'];
        return $access_token;
    }

    /**
     * curl的get方法
     * @param string $url
     * @param string $token
     * @return mixed
     */
    function get_curl($url = '', $token = '')
    {
        $ch = curl_init();
        if (!empty($token)) {
            $header = ['token:' . $token];
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        }
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0.8);
        $data = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        return json_decode($data, true);
    }

    /**
     * curl的post方法
     * @param string $url
     * @param string $post_data
     * @return mixed
     */
    function post_curl($url = '', $post_data = '')
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);
        curl_setopt($curl, CURLOPT_TIMEOUT, 30);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $data = curl_exec($curl);
        curl_close($curl);
        return $data;
    }
}
